package com.mrper.asm.click

import org.objectweb.asm.Handle
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.commons.AdviceAdapter
import org.objectweb.asm.tree.InvokeDynamicInsnNode
import org.objectweb.asm.tree.MethodNode

class ViewClickMethodDetectAdapter(
    api: Int,
    methodVisitor: MethodVisitor?,
    access: Int,
    name: String?,
    descriptor: String?,
    private val methodNode: MethodNode,
) : AdviceAdapter(api, methodVisitor, access, name, descriptor) {

    override fun visitInvokeDynamicInsn(name: String?, descriptor: String?, bootstrapMethodHandle: Handle?, vararg bootstrapMethodArguments: Any?) {
        // 确定它是点击事件
        if (name == ViewClickMethodConstants.ViewOnClickMethodName
            && descriptor?.endsWith(ViewClickMethodConstants.OnClickListenerDescriptor) == true) {
            println("lambda: visitInvokeDynamicInsn ===================================> \nname = $name, \n" +
                "descriptor = $descriptor,  \n" +
                "bootstrapMethodHandle = ${bootstrapMethodHandle?.name}|${bootstrapMethodHandle?.desc}|${bootstrapMethodHandle?.owner},  \n" +
                "bootstrapMethodArguments = $bootstrapMethodArguments")
            println("bootstrapMethodHandle:")
            println("name=${bootstrapMethodHandle?.name}")
            println("desc=${bootstrapMethodHandle?.desc}")
            println("owner=${bootstrapMethodHandle?.owner}")
            println("isInterface=${bootstrapMethodHandle?.isInterface}")
            println("tag=${bootstrapMethodHandle?.tag}")

            val dynamicNode = InvokeDynamicInsnNode(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments)
            val tag = ClickMethodTagInfo(methodNode.name, name, dynamicNode.desc)
            ViewClickRecordPool.clickLambdaMethodLookup.add(tag)
            println("dynamicNode ================ 动态方法调用")
            println("methodNode ================  ${methodNode.name}")
            println("name ================  ${dynamicNode.name}")
            println("desc ================  ${dynamicNode.desc}")
            println("bsm  ================ ${dynamicNode.bsm?.name}, ${dynamicNode.bsm?.desc}")
            println("bsmArgs  ================ ${dynamicNode.bsmArgs}")
        }
        super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, *bootstrapMethodArguments)
    }

}